home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / MPW_TOOL / TOOLS / TOOLS_WI / ICON_8 / ICONT_FO / TMAIN.C < prev    next >
C/C++ Source or Header  |  1990-03-12  |  12KB  |  474 lines

  1. /*
  2.  * tmain.c - main program for translator and linker.
  3.  */
  4.  
  5. #include "::h:config.h"
  6. #include "tproto.h"
  7. #include "::h:paths.h"
  8. #include "general.h"
  9.  
  10. /*
  11.  * Prototype.
  12.  */
  13.  
  14. novalue    execute    Params((char *ofile,char *efile,char * *args));
  15.  
  16. /*
  17.  * The following code is operating-system dependent [@tmain.01].  Include
  18.  *  files and such.
  19.  */
  20.  
  21. #if PORT
  22. Deliberate syntax error
  23. #endif                    /* PORT */
  24.  
  25. #if AMIGA || HIGHC_386 || MSDOS || MVS || UNIX || VM || VMS
  26. /* nothing is needed */
  27. #endif                    /* AMIGA || HIGHC_386 || ... */
  28.  
  29. #if ATARI_ST
  30. char *patharg;
  31. #endif                    /* ATARI_ST */
  32.  
  33. #if MACINTOSH
  34. #if MPW
  35. #include <fcntl.h>    /* MPW3 - for unlink() */
  36. #include <CursorCtl.h>
  37. void SortOptions();
  38. #endif                    /* MPW */
  39. #endif                    /* MACINTOSH */
  40.  
  41. #if OS2
  42. #include <process.h>
  43. #endif                    /* OS2 */
  44. /*
  45.  * End of operating-system specific code.
  46.  */
  47.  
  48. #ifdef strlen
  49. #undef strlen                /* pre-defined in some contexts */
  50. #endif                    /* strlen */
  51.  
  52. #ifndef Iconx
  53. #define Iconx IconxPath
  54. #endif                    /* Iconx */
  55.  
  56. /*
  57.  *  Define global variables.
  58.  */
  59.  
  60. #define Global
  61. #define Init(v) = v
  62. #include "globals.h"
  63.  
  64. char *ofile = NULL;            /* linker output file name */
  65.  
  66. /*
  67.  * getopt() variables
  68.  */
  69. extern int optind;        /* index into parent argv vector */
  70. extern int optopt;        /* character checked for validity */
  71. extern char *optarg;        /* argument associated with option */
  72.  
  73. /*
  74.  *  main program
  75.  */
  76. novalue main(argc,argv)
  77. int argc;
  78. char **argv;
  79.    {
  80.    int nolink = 0;            /* suppress linking? */
  81.    int errors = 0;            /* translator and linker errors */
  82.    char **tfiles, **tptr;        /* list of files to translate */
  83.    char **lfiles, **lptr;        /* list of files to link */
  84.    char **rfiles, **rptr;        /* list of files to remove */
  85.    char *efile = NULL;            /* stderr file */
  86.    char buf[MaxFileName];        /* file name construction buffer */
  87.    int c, n;
  88.    struct fileparts *fp;
  89.  
  90. #if MACINTOSH
  91. #if MPW
  92.    InitCursorCtl(NULL);
  93.    SortOptions(argv);
  94. #endif                    /* MPW */
  95. #endif                    /* MACINTOSH */
  96.  
  97.    /*
  98.     * Process options.
  99.     */
  100.    while ((c = getopt(argc,argv,Options)) != EOF)
  101.       switch (c) {
  102.          case 'c':            /* -c: compile only (no linking) */
  103.             nolink = 1;
  104.             break;
  105.          case 'e':            /* -e file: redirect stderr */
  106.             efile = optarg;
  107.             break;
  108.          case 'm':            /* -m: preprocess using m4(1) [UNIX] */
  109.             m4pre = 1;
  110.             break;
  111.          case 'o':            /* -o file: name output file */
  112.             ofile = optarg;
  113.             break;
  114.  
  115. #if ATARI_ST
  116.          case 'p':            /* -p path: iconx path [ATARI] */
  117.             patharg = optarg;
  118.             break;
  119. #endif                    /* ATARI_ST */
  120.  
  121.          case 's':            /* -s: suppress informative messages */
  122.             silent = 1;
  123.             break;
  124.          case 'u':            /* -u: warn about undeclared ids */
  125.             uwarn = 1;
  126.             break;
  127.          case 't':            /* -t: turn on procedure tracing */
  128.             trace = -1;
  129.             break;
  130.  
  131.  
  132.          case 'L':            /* -L: enable linker debugging */
  133.  
  134. #ifdef DeBugLinker
  135.             Dflag = 1;
  136. #endif                    /* DeBugLinker */
  137.  
  138.             break;
  139.  
  140.          case 'S':            /* -Sxnnnn: set a size */
  141.             sizearg(optarg,argv);
  142.             break;
  143.          default:
  144.          case 'x':            /* -x illegal until after file list */
  145.             usage();
  146.          }
  147.    /*
  148.     * Allocate space for lists of file names.
  149.     */
  150.    n = argc - optind + 1;
  151.    tptr = tfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  152.    lptr = lfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  153.    rptr = rfiles = (char **)alloc((unsigned int)(2 * n * sizeof(char *)));
  154.  
  155.    /*
  156.     * Scan file name arguments.
  157.     */
  158.    while (optind < argc)  {
  159.       if (strcmp(argv[optind],"-x") == 0)    /* stop at -x */
  160.          break;
  161.       else if (strcmp(argv[optind],"-") == 0) {
  162.          *tptr++ = "-";                /* "-" means standard input */
  163.          *lptr++ = *rptr++ = "stdin.u1";
  164.          *rptr++ = "stdin.u2";
  165.          }
  166.       else {
  167.          fp = fparse(argv[optind]);        /* parse file name */
  168.          if (*fp->ext == '\0' || smatch(fp->ext, SourceSuffix)) {
  169.             makename(buf,SourceDir,argv[optind], SourceSuffix);
  170.             *tptr++ = salloc(buf);        /* translate the .icn file */
  171.             makename(buf,TargetDir,argv[optind],U1Suffix);
  172.             *lptr++ = *rptr++ = salloc(buf);    /* link & remove .u1 */
  173.             makename(buf,TargetDir,argv[optind],U2Suffix);
  174.             *rptr++ = salloc(buf);        /* also remove .u2 */
  175.             }
  176.          else if (smatch(fp->ext,U1Suffix) || smatch(fp->ext,U2Suffix)
  177.                || smatch(fp->ext,USuffix)) {
  178.             makename(buf,TargetDir,argv[optind],U1Suffix);
  179.             *lptr++ = salloc(buf);
  180.             }
  181.          else
  182.             quitf("bad argument %s",argv[optind]);
  183.          }
  184.       optind++;
  185.       }
  186.  
  187.    *tptr = *lptr = *rptr = NULL;    /* terminate filename lists */
  188.    if (lptr == lfiles)
  189.       usage();                /* error -- no files named */
  190.  
  191.    /*
  192.     * Round hash table sizes to next power of two, and set masks for hashing.
  193.     */
  194.    chsize = round2(chsize);  cmask = chsize - 1;
  195.    fhsize = round2(fhsize);  fmask = fhsize - 1;
  196.    ghsize = round2(ghsize);  gmask = ghsize - 1;
  197.    ihsize = round2(ihsize);  imask = ihsize - 1;
  198.    lhsize = round2(lhsize);  lmask = lhsize - 1;
  199.  
  200.    /*
  201.     * Translate .icn files to make .u1 and .u2 files.
  202.     */
  203.    if (tptr > tfiles) {
  204.       if (!silent)
  205.          report("Translating");
  206.       errors = trans(tfiles);
  207.       if (errors > 0)            /* exit if errors seen */
  208.          exit(ErrorExit);
  209.       }
  210.  
  211.    /*
  212.     * Link .u1 and .u2 files to make an executable.
  213.     */
  214.    if (nolink) {            /* exit if no linking wanted */
  215.  
  216. #if MACINTOSH
  217. #if MPW
  218.       /*
  219.        *  Set type of translator output ucode (.u) files
  220.        *  to 'TEXT', so they can be easily viewed by editors.
  221.        */
  222.       {
  223.       char **p;
  224.       void setfile();
  225.       for (p = rfiles; *p; ++p)
  226.          setfile(*p,'TEXT','icon');
  227.       }
  228. #endif                    /* MPW */
  229. #endif                    /* MACINTOSH */
  230.  
  231.       exit(NormalExit);
  232.       }
  233.  
  234.    if (ofile == NULL)  {        /* if no -o file, synthesize a name */
  235.       ofile = salloc(makename(buf,TargetDir,lfiles[0],IcodeSuffix));
  236.    } else {                /* add extension in necessary */
  237.       fp = fparse(ofile);
  238.       if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given */
  239.          ofile = salloc(makename(buf,NULL,ofile,IcodeSuffix));
  240.    }
  241.  
  242.    if (!silent)
  243.       report("Linking");
  244.    errors = ilink(lfiles,ofile);    /* link .u files to make icode file */
  245.  
  246.    /*
  247.     * Finish by removing intermediate files.
  248.     *  Execute the linked program if so requested and if there were no errors.
  249.     */
  250.  
  251. #if MACINTOSH
  252. #if MPW
  253.    /* Set file type to TEXT so it will be executable as a script. */
  254.    setfile(ofile,'TEXT','icon');
  255. #endif                    /* MPW */
  256. #endif                    /* MACINTOSH */
  257.  
  258.    rmfiles(rfiles);            /* remove intermediate files */
  259.    if (errors > 0) {            /* exit if linker errors seen */
  260.       unlink(ofile);
  261.       exit(ErrorExit);
  262.       }
  263.  
  264. #if !(MACINTOSH && MPW)
  265.    if (optind < argc)  {
  266.       if (!silent)
  267.          report("Executing");
  268.       execute (ofile, efile, argv+optind+1);
  269.       }
  270. #endif                    /* !(MACINTOSH && MPW) */
  271.  
  272.    exit(NormalExit);
  273.    }
  274.  
  275. /*
  276.  * execute - execute iconx to run the icon program
  277.  */
  278. static novalue execute(ofile,efile,args)
  279. char *ofile, *efile, **args;
  280.    {
  281. #if !(MACINTOSH && MPW)
  282.    int n;
  283.    char **argv, **p;
  284.  
  285.    for (n = 0; args[n] != NULL; n++)    /* count arguments */
  286.       ;
  287.    p = argv = (char **)alloc((unsigned int)((n + 5) * sizeof(char *)));
  288.  
  289.    *p++ = Iconx;            /* set iconx pathname */
  290.    if (efile != NULL) {            /* if -e given, copy it */
  291.       *p++ = "-e";
  292.       *p++ = efile;
  293.       }
  294.    *p++ = ofile;            /* pass icode file name */
  295.  
  296. #if AMIGA && LATTICE
  297.    *p = *args;
  298.    while (*p++) {
  299.       *p = *args;
  300.       args++;
  301.    }
  302. #else                    /* AMIGA && LATTICE */
  303.    while (*p++ = *args++)        /* copy args into argument vector */
  304.       ;
  305. #endif                    /* AMIGA && LATTICE */
  306.  
  307.    *p = NULL;
  308.  
  309. /*
  310.  * The following code is operating-system dependent [@tmain.02].  It calls
  311.  *  iconx on the way out.
  312.  */
  313.  
  314. #if PORT
  315.    /* something is needed */
  316. Deliberate Syntax Error
  317. #endif                    /* PORT */
  318.  
  319. #if AMIGA
  320. #if AZTEC_C
  321.       execvp(Iconx,argv);
  322.       return;
  323. #endif                    /* AZTEC_C */
  324. #if LATTICE
  325.       {
  326.       struct ProcID procid;
  327.       if (forkv(Iconx,argv,NULL,&procid) == 0) { 
  328.          wait(&procid);
  329.          return;
  330.          }
  331.       }
  332. #endif                    /* LATTICE */
  333. #endif                    /* AMIGA */
  334.  
  335. #if ATARI_ST
  336.       /* Forkvp(Iconx,argv); */
  337.       /* return; */
  338.       fprintf(stderr,"-x not supported\n");
  339.       fflush(stderr);
  340.      /* not implemented yet */
  341. #endif                    /* ATARI_ST */
  342.  
  343. #if HIGHC_386 || MVS || VM
  344.       fprintf(stderr,"-x not supported\n");
  345.       fflush(stderr);
  346.      /* not implemented yet */
  347. #endif                    /* HIGHC_386 || MVS || VM */
  348.  
  349. #if MACINTOSH
  350.       fprintf(stderr,"-x not supported\n");
  351.       fflush(stderr);
  352. #endif                    /* MACINTOSH */
  353.  
  354. #if MSDOS
  355. #if LATTICE || MICROSOFT || TURBO
  356.       execvp(Iconx,argv);    /* execute with path search */
  357. #endif                    /* LATTICE || MICROSOFT || TURBO */
  358. #if MWC
  359.       fprintf(stderr,"-x not supported\n");
  360.       fflush(stderr);
  361.       /* execall(Iconx,argv); */
  362. #endif                    /* MWC */
  363. #endif                    /* MSDOS */
  364.  
  365. #if OS2
  366.       execvp(Iconx,argv);    /* execute with path search */
  367. #endif                    /* OS2 */
  368.  
  369. #if UNIX
  370.       /*
  371.        * If an ICONX environment variable is defined, use that.
  372.        *  If not, first try the predefined path, then search $PATH via execvp. 
  373.        */
  374.       if ((argv[0] = getenv("ICONX")) != NULL && argv[0][0] != '\0') {
  375.          execv(argv[0], argv);    /* exec file specified by $ICONX */
  376.          quitf("cannot execute $ICONX (%s)", argv[0]);
  377.          }
  378. #ifdef HardWiredPaths
  379.       argv[0] = Iconx;        /* try predefined file */
  380.       execv(argv[0], argv);
  381. #endif                    /* HardWiredPaths */
  382.       argv[0] = "iconx";
  383.       execvp(argv[0], argv);    /* if no Iconx, search path for "iconx" */
  384. #ifdef HardWiredPaths
  385.       quitf("cannot run %s", Iconx);
  386. #else                    /* HardWiredPaths */
  387.       quitf("cannot find iconx", "");
  388. #endif                    /* HardWiredPaths */
  389. #endif                    /* UNIX */
  390.  
  391. #if VMS
  392.       execv(Iconx,argv);
  393. #endif                    /* VMS */
  394.  
  395. /*
  396.  * End of operating-system specific code.
  397.  */
  398.  
  399.    quitf("could not run %s",Iconx);
  400. #else                    /* !(MACINTOSH && MPW) */
  401.    printf("-x not supported\n");
  402. #endif                    /* !(MACINTOSH && MPW) */
  403.    }
  404.  
  405. static novalue report(s)
  406. char *s;
  407.    {
  408.  
  409. /*
  410.  * The following code is operating-system dependent [@tmain.03].  Report
  411.  *  phase.
  412.  */
  413.  
  414. #if PORT
  415.    fprintf(stderr,"%s:\n",s);
  416. Deliberate Syntax Error
  417. #endif                    /* PORT */
  418.  
  419. #if AMIGA || ATARI_ST || HIGHC_386 || MSDOS || MVS || OS2 || UNIX || VM || VMS
  420.    fprintf(stderr,"%s:\n",s);
  421. #endif                    /* AMIGA || ATARI_ST || HIGHC_386 ... */
  422.  
  423. #if MACINTOSH
  424.    fprintf(stderr,"%s:\n",s);
  425. #endif                    /* MACINTOSH */
  426.  
  427. /*
  428.  * End of operating-system specific code.
  429.  */
  430.  
  431.    }
  432.  
  433. /*
  434.  * rmfiles - remove a list of files
  435.  */
  436.  
  437. static novalue rmfiles(p)
  438. char **p;
  439.    {
  440.    for (; *p; p++) {
  441. /*
  442.  * The following code is operating-system dependent [@tmain.04].
  443.  *  remove files.
  444.  */
  445.  
  446. #if PORT
  447.       unlink(*p);
  448. Deliberate Syntax Error
  449. #endif                    /* PORT */
  450.  
  451. #if AMIGA || ATARI_ST || HIGHC_386 || MSDOS || MVS || OS2 || UNIX || VM || VMS
  452.       unlink(*p);
  453. #endif                    /* AMIGA || ATARI_ST ... */
  454.  
  455. #if MACINTOSH
  456.       unlink(*p);
  457. #endif                    /* MACINTOSH */
  458.  
  459. /*
  460.  * End of operating-system specific code.
  461.  */
  462.       }
  463.    }
  464.  
  465. /*
  466.  * Print an error message if called incorrectly.  The message depends
  467.  *  on the legal options for this system.
  468.  */
  469. static novalue usage()
  470.    {
  471.    fprintf(stderr,"usage: %s %s file ... [-x args]\n", progname, Usage);
  472.    exit(ErrorExit);
  473.    }
  474.